#include "stdafx.h"
#include "CppUnitTest.h"

#include "System/Base/RuntimeException.h"
#include "System/Base/Scene.h"
#include "System/Base/Case.h"


using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Native::System;

namespace TestNativeSystem
{
    TEST_CLASS(RuntimeException_Tester)
    {
    public:
        wstring _class;
        wstring _detail;
        wstring _arguments;
        size_t _line;

        RuntimeException_Tester()
        {
            _class = L"RuntimeException_Tester";
            _detail = L"Test exception detail";
            _arguments = L"location";
            _line = 189;
        }

        TEST_CLASS_INITIALIZE(ClassInitialize)
        {
        };

        TEST_METHOD(RuntimeException_Throw)
        {
            CScene location(_class, L"RuntimeException_Throw", _line);
            wstring typeName;
            wstring message = L"The Message";

            try {
                CRuntimeException exception(location, message, EMPTY_STRING, _detail);
                typeName = exception.TypeName();

                throw exception;
            } catch(CException& e) {
                Assert::AreEqual(e.TypeName(), typeName);

                auto testee = e.LatestRecord();

                Assert::AreEqual(testee.Scene().Class(), _class);
                Assert::AreEqual(testee.Scene().Method().c_str(), L"RuntimeException_Throw");
                Assert::AreEqual(testee.Scene().Line(), 189u);
                Assert::AreEqual(testee.Message(), message);
                Assert::AreEqual(testee.Arguments(), EMPTY_STRING);
                Assert::AreEqual(testee.Detail(), _detail);
            }
        }

        TEST_METHOD(RuntimeException_CheckWithoutArgument)
        {
            CScene location(_class, L"RuntimeException_CheckWithoutArgument", _line);
            wstring message = L"The Message";

            try {
                CRuntimeException::Check(
                    location, [](wstring& message){message = L"The Message"; return false;}, _arguments, _detail);
            } catch(CException& e) {
                auto testee = e.LatestRecord();

                Assert::AreEqual(testee.Scene().Class(), _class);
                Assert::AreEqual(testee.Scene().Method().c_str(), L"RuntimeException_CheckWithoutArgument");
                Assert::AreEqual(testee.Scene().Line(), 189u);
                Assert::AreEqual(testee.Message(), message);
                Assert::AreEqual(testee.Arguments(), _arguments);
                Assert::AreEqual(testee.Detail(), _detail);
            }
        }
    };
}